/* 
 * Author: Vassilis
 */

#ifndef _TILE_H
#define	_TILE_H

#include "Rect.h"

class Tileset;

class Tile
{
private:
    /**
     * Mask used to determine if one gid is flipped in X axis.
     */
    static const unsigned int maskX = 0x80000000;

    /**
     * Mask used to determine if one gid is flipped in Y axis.
     */
    static const unsigned int maskY = 0x40000000;

    Math::Rect m_clip;
    unsigned long m_flag;
    Tileset *m_tileset;
    int m_gid;
    bool m_flipX;
    bool m_flipY;
public:
    Tile(unsigned int sGid = 0, unsigned long flag = 0);
    
    ~Tile();
    
    void SetRect(unsigned x, unsigned y, unsigned width, unsigned height);
    
    void SetRect(const Math::Rect &rect);
    
    void SetGid(int sGid);
    
    /**
     * 
     * @return the true id of this tileset regardless of its flips.
     * Use this when flipping doesn't matter. ex. On collision calculations.
     */
    int GetTilesetID() const;
    
    void SetTileset(Tileset *sTileset);
    
    Tileset *GetTileset();
    
    /**
     * 
     * @return the gid of this tile based on its flips.
     * Use this when flipping matters. ex. On drawing.
     */
    int GetGid() const;
    
    const Math::Rect &GetClip() const;

    /**
     * Clears out the flag.
     */
    inline void ClearFlag()
    {
        m_flag ^= m_flag;
    }

    /**
     * Adds a flag to this tile.
     */
    inline void AddToFlag(unsigned int value)
    {
        m_flag |= value;
    }

    /**
     * Removes a mask from the tile.
     */
    inline void RemoveFromFlag(unsigned int value)
    {
        m_flag = m_flag ^ value;
    }

    /**
     * Returns true if this tile is value.
     */
    inline bool CheckFlag(unsigned int value)
    {
        return m_flag & value;
    }

    inline unsigned long GetFlag()
    {
        return m_flag;
    }
    bool IsFlipY() const;
    bool IsFlipX() const;
};

#endif	/* _TILE_H */
